package ca.csf.dfc.poo.environnement;

import ca.csf.dfc.poo.exceptions.IllegalPositionXException;
import ca.csf.dfc.poo.exceptions.IllegalPositionYException;
import ca.csf.dfc.poo.exceptions.IllegalRecompenseException;
import ca.csf.dfc.poo.exceptions.IllegalTableauDecisionException;
import ca.csf.dfc.poo.exceptions.InvalidDirectionException;

/**
 * Cette classe est la classe de base pour tous les robots
 * @author �quipe 1
 *
 */
public abstract class Robot {
	
	/**
	 * Constante int pour d�finir les directions haut, droite, bas et gauche.
	 */
	public static final int AUCUNE = -1,HAUT = 0, DROITE = 1, BAS = 2, GAUCHE = 3;
	
	/**
	 * Position du robot sur l'axe des abscisses.
	 */
	protected int m_X;
	
	/**
	 * Position du robot sur l'axe des ordonn�es.
	 */
	protected int m_Y;
	
	/**
	 * Total des r�compenses accumul�es par le robot.
	 */
	protected int m_RecompenseAccumulees;
	
	/**
	 * Constructeur par initialisation recevant la position en x et y du robot.
	 * @param p_X : Position sur l'axe des abscisses.
	 * @param p_Y : Position sur l'axe des ordonn�es.
	 * @throws IllegalPositionXException,IllegalPositionYException 
	 * @throws IllegalPositionYException 
	 * @throws IllegalRecompenseException 
	 */
	public Robot(int p_X, int p_Y) throws IllegalPositionXException, IllegalPositionYException, IllegalRecompenseException
	{
		this.setX(p_X);
		this.setY(p_Y);
		this.setRecompense(0);
	}
	
	/**
	 * D�termine une nouvelle position du robot sur l'axe des abscisses.
	 * @param p_X : Valeur sur l'axe des abscisses.
	 * @throws IllegalPositionXException 
	 */
	protected void setX(int p_X) throws IllegalPositionXException
	{
	    //On génère une exception dans le cas ou la position X est < que 0.
	    if (p_X < 0)
            throw new IllegalPositionXException();
	    
		this.m_X = p_X;
	}
	
	/**
	 * Permet de conna�tre la position du robot sur l'axe des abscisses.
	 * @return La position du robot sur l'axe des abscisses.
	 */
	public int getX()
	{
		return this.m_X;
	}
	
	/**
	 * D�termine une nouvelle position du robot sur l'axe des ordonn�es.
	 * @param p_Y : Valeur sur l'axe des ordonn�es.
	 * @throws IllegalPositionYException 
	 */
	protected void setY(int p_Y) throws IllegalPositionYException
	{
	  //On génère une exception dans le cas ou la position Y est < que 0.
        if (p_Y < 0)
            throw new IllegalPositionYException();
        
		this.m_Y = p_Y;
	}
	
	/**
	 * Permet de conna�tre la position du robot sur l'axe des ordonn�es.
	 * @return La position du robot sur l'axe des ordonn�es.
	 */
	public int getY()
	{
		return this.m_Y;
	}
	
	/**
	 * Fixe les r�compenses accumulees.
	 * @param p_Recompense : Nouveau nombre correspondant aux r�compenses accumul�es.
	 * @throws IllegalRecompenseException 
	 */
	protected void setRecompense(int p_Recompense) throws IllegalRecompenseException
	{
	    //On génère une exception si la récompense est négative.
	    if (p_Recompense < 0)
	        throw new IllegalRecompenseException();
	    
		this.m_RecompenseAccumulees = p_Recompense;
	}
	
	/**
	 * R�cup�re les r�compenses accumul�es.
	 * @return Le nombre correspondant aux r�compenses accumul�es.
	 */
	public int getRecompense()
	{
		return this.m_RecompenseAccumulees;
	}
	
	/**
	 * Permet au robot de recevoir une r�compense.
	 * @param p_Recompense : R�compense � ajouter au total.
	 * @throws IllegalRecompenseException 
	 */
	public void recevoirRecompense(int p_Recompense) throws IllegalRecompenseException
	{
		this.setRecompense(this.getRecompense()+p_Recompense);
	}
	
	/**
	 * Permet de déplacer le robot à une position X et Y donné.
	 * @param p_X : Position sur l'axe des X.
	 * @param p_Y : Position sur l'axe des Y.
	 * @throws IllegalPositionXException 
	 * @throws IllegalPositionYException 
	 */
	public void deplacer(int p_X, int p_Y) throws IllegalPositionXException, IllegalPositionYException
	{
	    this.setX(p_X);
	    this.setY(p_Y);
	}
	
	/**
	 * Permet au robot de se d�placer en prenant une d�cision selon les cases qui l'entoure.
	 * @param p_Haut : Case situ�e en haut de la position pr�sente.
	 * @param p_Droit : Case situ�e � droite de la position pr�sente.
	 * @param p_Bas : Case situ�e en bas de la position pr�sente.
	 * @param p_Gauche : Case situ�e � gauche de la position pr�sente.
	 */
	public abstract int prendreDecision(Case[] p_TabCases) throws IllegalTableauDecisionException,IllegalPositionXException, IllegalPositionYException, InvalidDirectionException;
}
